package com.networkviwer.networkviewer;

import com.networkviwer.buttons.CommonButton;
import com.networkviwer.swing.CommonTable;
import com.networkviwer.utils.UnionDatasourceUtil;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

/**
 * @version V1.0
 * @Title:
 * @Package
 * @Description:
 * @author: runoob
 * @date:
 */
public class NetworkViewer implements Runnable {

    private static JFrame main = new JFrame("NetworkViewer - ver1.0");
    private static Container contentPane = main.getContentPane();
    //初始化table和相关组件
    private static CommonTable table;
    private static JScrollPane jScrollPane;
    private static JPanel tablePanel = new JPanel();
    //初始化功能栏和相关组件（输入框、按钮）
    private static JPanel bar = new JPanel();
    private static JPanel port = new JPanel();
    private static JPanel pid = new JPanel();
    private static JPanel image = new JPanel();
    //分割线，用于分割按钮区和输入区
    private static JLabel divide = new JLabel(" | ");
    private static JLabel portLabel = new JLabel("端口:");
    private static JLabel pidLabel = new JLabel("pid:");
    private static JLabel imageLabel = new JLabel("名称:");
    private static JTextField portField = new JTextField(20);
    private static JTextField pidField = new JTextField(20);
    private static JTextField imageField = new JTextField(20);
    //自动刷新按钮
    public static CommonButton autoBtn;
    //手动刷新按钮
    public static CommonButton refreshBtn;
    //是否展示tcp协议按钮
    public static CommonButton tcpBtn;
    //是否展示udp协议按钮
    public static CommonButton udpBtn;
    //查询按钮
    public static CommonButton searchBtn;
    //定义二维数组作为表格数据
    static Object[][] tableData = new Object[10000][9];
    //定义一维数据作为列标题
    static Object[] columnTitle = {"协议" , "本地地址" , "外部地址", "状态", "PID", "名称", "会话名", "会话数", "内存使用"};
    static String[] columnNames = {"protocol" , "local_address" , "external_address" , "status" , "pid" , "image" , "session" , "session_num" , "memory_usage"};
    //对应列的排序状态，0为不排序，1为正序，-1为倒序
    static public int pidOrder = 0;
    static public int imageOder = 0;
    //公共查询条件map，用于传参
    static public Map<String,String> valueMap = new HashMap<>();

    /**
     * 主程序
     */
    public NetworkViewer() throws IOException {
        //组装table
        setTable();
        //组装按钮
        setButton();
        //组装窗口
        setFrame();
        //初始化传参map
        setValueMap();
    }

    /**
     * 组装table
     */
    static public void setTable(){
        //以二维数组和一维数组来创建一个JTable对象
        table = new CommonTable(tableData , columnTitle);
        //设置列宽
        javax.swing.table.TableColumnModel tcm = table.getColumnModel();
        tcm.getColumn(1).setPreferredWidth(300);
        tcm.getColumn(2).setPreferredWidth(300);
        tcm.getColumn(3).setPreferredWidth(200);
        tcm.getColumn(4).setPreferredWidth(200);
        tcm.getColumn(5).setPreferredWidth(350);
        tcm.getColumn(6).setPreferredWidth(200);
        tcm.getColumn(8).setPreferredWidth(120);
    }

    /**
     * 组装按钮
     */
    public void setButton() throws IOException {
        //加载按钮图片
        BufferedImage autoImg = ImageIO.read(new File("resources/images/auto.png"));
        BufferedImage refreshImg = ImageIO.read(new File("resources/images/refresh.png"));
        BufferedImage tcpImg = ImageIO.read(new File("resources/images/TCP.png"));
        BufferedImage udpImg = ImageIO.read(new File("resources/images/UDP.png"));
        BufferedImage searchImg = ImageIO.read(new File("resources/images/search.png"));
        //初始化按钮属性
        autoBtn = new CommonButton(autoImg,0,0,40,40);
        autoBtn.setHoldListener();
        refreshBtn = new CommonButton(refreshImg,45,0,40,40);
        refreshBtn.addActionListener(new refreshBtn());
        tcpBtn = new CommonButton(tcpImg,90,0,40,40);
        tcpBtn.setHoldListener();
        udpBtn = new CommonButton(udpImg,135,0,40,40);
        udpBtn.setHoldListener();
        searchBtn = new CommonButton(searchImg,180,0,40,40);
        searchBtn.addActionListener(new searchBtn());
        //设置自动刷新和展示tcp协议为默认开启状态
        autoBtn.hold();
        tcpBtn.hold();
//        udpBtn.hold();
        main.getRootPane().setDefaultButton(searchBtn);
    }

    /**
     * 组装窗口
     */
    public void setFrame() throws IOException {
        //将JTable对象放在JScrollPane中，并将该JScrollPane放在窗口中显示出来
        jScrollPane = new JScrollPane(table);
        //内容面板
        contentPane.setLayout(null);
        //组装输入区
        setSearchLabel();
        //设置整个窗口的颜色
        setBgColor();
        //把组件添加到主面板
        setContentPane();
        //设置图标
        main.setIconImage(ImageIO.read(new File("resources/logo.png")));
        main.pack();
        //设置窗口大小
        main.setSize(1500,800);
        //设置程序启动时窗口出现的位置
        int screenWidth= java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
        int screenHeight = java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;
        main.setLocation((screenWidth-1500)/2, (screenHeight-800)/2);
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main.setVisible(true);
    }

    /**
     * 组装输入区
     */
    public void setSearchLabel(){
        divide.setForeground(Color.WHITE);
        divide.setFont(new Font("Menu.font", Font.PLAIN, 20));
        portLabel.setForeground(Color.WHITE);
        portLabel.setFont(new Font("Menu.font", Font.PLAIN, 16));
        pidLabel.setForeground(Color.WHITE);
        pidLabel.setFont(new Font("Menu.font", Font.PLAIN, 16));
        imageLabel.setForeground(Color.WHITE);
        imageLabel.setFont(new Font("Menu.font", Font.PLAIN, 16));
    }

    /**
     * 设置整个窗口的颜色
     */
    public void setBgColor(){
        Color bgColor = new Color(67,67,67);
        contentPane.setBackground(bgColor);
        port.setBackground(bgColor);
        pid.setBackground(bgColor);
        image.setBackground(bgColor);
        tablePanel.setBackground(bgColor);
        bar.setBackground(bgColor);
    }

    /**
     * 组装主面板
     */
    public void setContentPane(){
        port.add(portLabel);
        port.add(portField);
        pid.add(pidLabel);
        pid.add(pidField);
        image.add(imageLabel);
        image.add(imageField);
        bar.add(autoBtn);
        bar.add(refreshBtn);
        bar.add(tcpBtn);
        bar.add(udpBtn);
        bar.add(divide);
        bar.add(port);
        bar.add(pid);
        bar.add(image);
        bar.add(searchBtn);
        tablePanel.add(jScrollPane);
        bar.setLayout(new FlowLayout(FlowLayout.LEFT));
        bar.setBounds(5,5,1490,45);
        tablePanel.setBounds(0,50,1490,735);
        contentPane.setBounds(0,0,1500,800);
        contentPane.add(bar);
        contentPane.add(tablePanel);
    }

    /**
     * 初始化/重置valueMap
     */
    public void setValueMap(){
        valueMap.put("local_address","");
        valueMap.put("pid","");
        valueMap.put("image","");
    }

    /**
     * 刷新窗口
     */
    static public void refreshFrame(){
        main.invalidate();
        main.validate();
        main.repaint();
    }

    /**
     * 刷新table的数据
     */
    static public void refreshData() throws SQLException, ClassNotFoundException {
        //初始化数据库连接
        Connection connection = UnionDatasourceUtil.getConnection();
        Statement statement = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
        //获取查询结果
        ResultSet resultSet = UnionDatasourceUtil.getAllData(statement,valueMap);
        //结果集指针指到最后一行数据，用于获取结果总数
        resultSet.last();
        int resultSetLength = resultSet.getRow();
        //结果集指针指到开头
        resultSet.beforeFirst();
        //根据结果总数初始化对应大小的table
        tableData = new Object[resultSetLength][9];
        //遍历结果集并将数据存入数组
        for (int m=0;m<resultSetLength;m++){
            resultSet.next();
            for (int n=0;n<9;n++){
                tableData[m][n] = resultSet.getString(columnNames[n]);
            }
        }
        // 关闭链接
        resultSet.close();
        statement.close();
        connection.close();
        //组装table
        setTable();
        //刷新table区
        tablePanel.remove(jScrollPane);
        jScrollPane = new JScrollPane(table);
        tablePanel.add(jScrollPane);
        //刷新窗口
        refreshFrame();
    }

    /**
     * 手动刷新按钮监听器
     */
    private static class refreshBtn implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                refreshData();
            } catch (SQLException | ClassNotFoundException ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * 查询按钮监听器
     */
    private static class searchBtn implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            //从输入框获取输入参数并存入valueMap
            valueMap.put("local_address",portField.getText());
            valueMap.put("pid",pidField.getText());
            valueMap.put("image",imageField.getText());
            try {
                refreshData();
            } catch (SQLException | ClassNotFoundException ex) {
                ex.printStackTrace();
            }
        }

    }

    /**
     * 使用线程自动刷新数据
     */
    public void run() {
        Thread netstatUpdate = new Thread(() -> {
            while(true){
                if (autoBtn.getStatus() == 1){
                    try{
                        refreshData();
                        Thread.sleep(5432);
                    }catch(Throwable t){
                        t.printStackTrace();
                    }
                }else {
                    try{
                        Thread.sleep(5432);
                    }catch(Throwable t){
                        t.printStackTrace();
                    }
                }
            }
        });
        netstatUpdate.start();
    }

}
